/*
 * @Description:
 * @Author: your name
 * @version:
 * @Date: 2024-05-08 16:11:33
 * @LastEditors: your name
 * @LastEditTime: 2024-09-10 09:39:09
 */
import { defineStore } from 'pinia';
import * as Cesium from 'cesium';
import ConeGlowBottomCircleMaterialProperty from '@/cesiumTools/texutruedCircle.js';
import SimpleLabel from '../cesiumTools/Bubble/htmlMarker';
import { displayByName } from '@/cesiumTools/effectController';
import {changeStations} from '@/store/staticData.js'

export const useLineData = defineStore('lineData', {
  state: () => {
    return {
      lineData: [],
      // 全局共享viewer，注意标记为markRaw
      viewer: null,
      tileset: null,
    };
  },
  getters: {
    Viewer() {
      return this.viewer;
    },
    Tile() {
      return this.tileset;
    },
    // 获取线路显示隐藏信息
    lineDisplay() {
      return this.lineData.map(item => ({
        name: item.checked,
        id: item.id,
        name: item.name,
      }));
    },
    // 获取全部信息
    allData() {
      return this.lineData;
    },
  },
  actions: {
    setData(data) {
      return new Promise((resolve, reject) => {
        this.lineData = data.length ? data : [];
        resolve(data);
      });
    },
    setViewer(viewer) {
      return new Promise((resolve, reject) => {
        this.viewer = viewer;
        resolve(viewer);
      });
    },
    setTileset(tileset) {
      return new Promise((resolve, reject) => {
        this.tileset = tileset;
        resolve(tileset);
      });
    },
    // 全局管理路线显隐
    displayLine(lineNames, isShow) {
      if (Array.isArray(lineNames) && this.lineData.length && !this.disable) {
        const stationNames = [];
        // 控制state数据
        this.lineData.forEach(item => {
          const { stationsList, name } = item;
          if (lineNames.includes(name)) {
            item.checked = isShow;
            stationsList.forEach(station => {
              stationNames.push(station.name);
            });
          }
        });
        // 控制地图元素
        displayByName(lineNames, stationNames, isShow);
      }
    },
    // 控制全部图层显示隐藏
    controlAll(isShow) {
      const lines = [];
      const stations = [];
      this.lineData.forEach(line => {
        lines.push(line.name); // 添加线路名称
        line.stationsList.forEach(station => {
          stations.push(station.name); // 添加车站名称
        });
      });
      console.log(lines, stations, isShow)
      // 控制地图元素
      displayByName(lines, stations, isShow);
    },
    // 设置是否开启全局管理
    disableController(val) {
      this.disable = val;
    },
  },
});

export const useMeasureData = defineStore('measureData', {
  state: () => {
    return {
      measureData: [],
    };
  },
  getters: {
    // 获取全部信息
    allData() {
      return this.measureData;
    },
  },
  actions: {
    setData(data) {
      return new Promise((resolve, reject) => {
        this.measureData = data.length ? data : [];
        resolve(data);
      });
    },
    clearData() {
      return new Promise((resolve, reject) => {
        const data = this.measureData.map(item => {
          item.length && item.forEach(n => (n.measures.length = 0));
          return item;
        });
        this.measureData = data;
        resolve(data);
      });
    },
  },
});

// 光锥
export const coneWithLight = (viewer, options) => {
  const position = Cesium.defaultValue(options.position, Cesium.Cartesian3.ZERO);
  const height = Cesium.defaultValue(options.height, 700);
  const bottomRadius = Cesium.defaultValue(options.bottomRadius, 100);
  const color = Cesium.defaultValue(options.color, Cesium.Color.AQUA);
  const modelMatrix = Cesium.Matrix4.multiplyByTranslation(
    Cesium.Transforms.eastNorthUpToFixedFrame(position),
    new Cesium.Cartesian3(0.0, 0.0, height * 0.5),
    new Cesium.Matrix4()
  );

  const cylinderGeometry = new Cesium.CylinderGeometry({
    length: height,
    topRadius: 0.0,
    bottomRadius: bottomRadius * 0.7,
    vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat,
  });

  const cone = new Cesium.GeometryInstance({
    geometry: cylinderGeometry,
    modelMatrix: modelMatrix,
  });

  return viewer.scene.primitives.add(
    new Cesium.Primitive({
      geometryInstances: [cone],
      appearance: new Cesium.MaterialAppearance({
        material: new Cesium.Material({
          fabric: {
            type: 'VtxfShader1',
            uniforms: {
              color: color,
            },
            source: /*glsl*/ `
                          uniform vec4 color;   
                          czm_material czm_getMaterial(czm_materialInput materialInput)
                          {
                              czm_material material = czm_getDefaultMaterial(materialInput);
                              vec2 st = materialInput.st;
                              float time=fract(czm_frameNumber/10.0);
                              float isAlpha=step(0.5,time);
                              float dis = distance(st, vec2(0.5)); 
                              material.diffuse =1.9 * color.rgb;
                              if(isAlpha>=1.0){
                                  material.alpha = color.a * dis *2.0;
                              }else{
                                  material.alpha = color.a * dis *1.5;
                              }

                              return material;
                          }
                      `,
          },
          translucent: false,
        }),
        faceForward: false, // 当绘制的三角面片法向不能朝向视点时，自动翻转法向，从而避免法向计算后发黑等问题
        closed: true, // 是否为封闭体，实际上执行的是是否进行背面裁剪
      }),
    })
  );
};
// 站点底部圆环
export const bottomCircle = (viewer, options) => {
  const position = Cesium.defaultValue(options.position, Cesium.Cartesian3.ZERO);
  const color = Cesium.defaultValue(options.color, Cesium.Color.AQUA);
  const bottomRadius = Cesium.defaultValue(options.bottomRadius, 100);
  return viewer.entities.add({
    position: position,
    ellipse: {
      semiMinorAxis: bottomRadius * 2,
      semiMajorAxis: bottomRadius * 2,
      height: 0.0,
      material: new ConeGlowBottomCircleMaterialProperty(color),
    },
  });
};

// 渲染站点  传入颜色十六进制字符串，名称，位置{lng,lat,height}
const stations = [];
export const renderStation = (viewer, options) => {
  const position = Cesium.defaultValue(options.positions, {
    lng: 0,
    lat: 0,
  });
  const positionCar3 = Cesium.Cartesian3.fromDegrees(position.lng, position.lat);
  const conePrimitve = coneWithLight(viewer, {
    position: positionCar3,
    height: 700,
    bottomRadius: 100,
    color: Cesium.Color.fromCssColorString(options.color),
  });

  const bottomCircleEntity = bottomCircle(viewer, {
    position: positionCar3,
    bottomRadius: 100,
    color: Cesium.Color.fromCssColorString(options.color),
  });
  const target = {
    conePrimitve,
    bottomCircleEntity,
    name: options.name,
  };
  stations.push(target);
  return target;
};

// 删除单个站点，直接删除，而不是隐藏
export const removeStationByName = (viewer, name) => {
  const target = stations.find(item => item.name === name);
  if (target) {
    const { conePrimitve, bottomCircleEntity } = target;
    viewer.scene.primitives.remove(conePrimitve);
    viewer.entities.remove(bottomCircleEntity);
    stations.splice(stations.indexOf(target), 1);
  }
};

// 删除所有站点
export const removeAllStations = viewer => {
  stations.forEach(item => {
    const { conePrimitve, bottomCircleEntity } = item;
    viewer.scene.primitives.remove(conePrimitve);
    viewer.entities.remove(bottomCircleEntity);
  });
  stations.length = 0;
};

// 通过名称Array控制站点显示隐藏
export const hideStationByName = (names, isShow) => {
  const targets = stations.filter(item => names.indexOf(item.name) > -1);
  if (targets.length) {
    targets.forEach(target => {
      const { conePrimitve, bottomCircleEntity } = target;
      conePrimitve.show = isShow;
      bottomCircleEntity.show = isShow;
    });
  }
};

// 创建地铁线路 positions:[{lng,lat,height}]
// color:十六进制颜色字符串
// name:线路名称
export const lines = [];
export const renderLines = (viewer, options) => {
  //const lineStore = useLineData(); // 引入 Pinia 的 store
  const positions = Cesium.defaultValue(options.positions, [
    {
      lng: 0,
      lat: 0,
    },
  ]);
  const color = Cesium.defaultValue(options.color, Cesium.Color.AQUA);
  const name = Cesium.defaultValue(options.name, 'line');
  let positionArr = [];
  for (let i of positions) {
    positionArr.push(Number(i.lng), Number(i.lat));
  }
  const positionRes = Cesium.Cartesian3.fromDegreesArray(positions);
  const lineEnt = viewer.entities.add({
    name,
    polyline: {
      positions: positionRes,
      width: 10,
      //使用cesium默认的泛光线
      material: new Cesium.PolylineGlowMaterialProperty({
        color: color,
        glowPower: 0.12,
      }),
    },
  });
  lines.push(lineEnt);
  return lineEnt;
};

// 删除地铁线路，不是隐藏
export const removeAllLines = viewer => {
  lines.forEach(line => {
    line && viewer.entities.remove(line);
  });
};

// 通过名称控制线路显示隐藏
export const hideLineByName = (names, isShow) => {
  lines.forEach(line => {
    if (names.indexOf(line.name) > -1) {
      line.show = isShow;
    }
  });
};

// 渲染全部
const arr = []
export const renderAll = (viewer, dataSource) => {
  //console.log(dataSource);
  // 渲染道路
  if (dataSource.length) {
    dataSource.forEach(item => {
      const { paths, name, color, stationsList } = item;
      const position = [];
      paths.forEach(path => {
        position.push(path.lng, path.lat);
      });
      //console.log(position);
      renderLines(viewer, {
        positions: position,
        color: new Cesium.Color.fromCssColorString(color),
        name,
      });
      // 渲染站点
      stationsList.forEach(station => {
        const { position, name } = station;
        if (changeStations.includes(name)) {
          //station.color = '#e10602'
          arr.push(station)
          return
        }
        //isChange为1即换乘
        renderStation(viewer, {
          positions: position,
          name,
          color: station.color ? station.color : color,
        });
      });
    });
  }
  //去除重复站点
  const newArr = arr.filter((item, index) => {
    return arr.findIndex(i => i.name === item.name) === index;
  });
  newArr.forEach(item => {
    const { position, name } = item;
    const color = '#e10602'
    renderStation(viewer, {
      positions: position,
      name,
      color: color,
    });
  })
};

// 清除全部
export const removeAll = viewer => {
  removeAllLines(viewer);
  removeAllStations(viewer);
};

//站点气泡框
const billboards = [];
// 渲染站点标牌，后期还要添加点击查询功能
export const renderStationBill = async (viewer, options) => {
  const position = Cesium.defaultValue(options.position, {
    lng: 0,
    lat: 0,
  });
  const height = Cesium.defaultValue(options.height, 720);
  const name = Cesium.defaultValue(options.name, '站点');
  const show = Cesium.defaultValue(options.show, true);
  const color = Cesium.defaultValue(options.color, '#ff0000');
  const attr = Cesium.defaultValue(options.attr, {});
  const isCache = Cesium.defaultValue(options.isCache, true);
  const billControler = new SimpleLabel(viewer, {
    position: Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height),
    label: name,
    isShow: show,
    color: color,
    scaleByDistance: new Cesium.NearFarScalar(1000, 1, 20000, 0.4),
    attr: attr,
    type: 'marker',
  });
  await billControler.addLabel();

  const target = {
    billControler,
    billboard: billControler.vmInstance.el,
    name,
  };
  isCache && billboards.push(target);
  return target;
};

// 清除所有站点标牌
export const removeAllBillboards = () => {
  billboards.forEach(item => {
    const { billControler } = item;
    billControler.removeMarker();
    billControler.queryPopup && billControler.removeQueryPopup();
  });
};

// 根据名称Array控制站点标牌显示与隐藏
export const changeDisplayBillBoard = (names, isShow) => {
  const filterBills = billboards.filter(item => names.indexOf(item.billControler.label) > -1);
  filterBills.forEach(item => {
    const { billboard, billControler } = item;
    billControler.isDisplay = isShow;
    billboard.style.display = isShow ? 'block' : 'none';
  });
};

// 由于lineData的state是异步的，所以需要监听action来获取数据
export const watchLineData = (actionName = 'setData') => {
  return new Promise((resolve, reject) => {
    useLineData().$onAction(({ name, store, args, after, onError }) => {
      if (name === actionName) {
        after(res => {
          console.log(res);
          if (res) {
            resolve(res);
          }
        });

        onError(e => {
          reject(e);
        });
      }
    });
  });
};
